package com.robot.service.impl;

import algorithm.AlgorithmCaller;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.robot.common.api.CurrentUserSupport;
import com.robot.common.enums.ActionUnitTemplateCode;
import com.robot.common.exception.BusinessException;
import com.robot.dao.dto.IDDTO;
import com.robot.dao.dto.QueryRobotDetailDTO;
import com.robot.dao.dto.SendMessageDTO;
import com.robot.dao.entity.ActionUnit;
import com.robot.dao.entity.ChatHistory;
import com.robot.dao.entity.File;
import com.robot.dao.feigndto.actionunitdto.*;
import com.robot.dao.feigndto.chatdto.ChatTextStreamRequest;
import com.robot.dao.feigndto.chatdto.ExcelStreamRequest;
import com.robot.dao.feigndto.chatdto.PictureStreamRequest;
import com.robot.dao.mapper.*;
import com.robot.dao.vo.ChatVO;
import com.robot.repository.RobotRepoEntity;
import com.robot.repository.RobotRepository;
import com.robot.service.ChatService;
import com.robot.service.IntegralService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Flux;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ChatServiceImpl implements ChatService {

    @Autowired
    private ChatMapper chatMapper;

    @Autowired
    private ActionUnitMapper actionUnitMapper;

    @Autowired
    private BulkFileMapper bulkFileMapper;

    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    private RobotKnowledgeMapper robotKnowledgeMapper;

    @Autowired
    private RobotRepository robotRepository;


    @Value("${chatConfig.messageSendNumber}")
    private Integer messageSendNumber;
    @Value("${chatConfig.chatHistoryNumber}")
    private Integer chatHistoryNumber;
    @Qualifier("robotMapper")
    @Autowired
    private RobotMapper robotMapper;

    @Autowired
    private AlgorithmCaller algorithmCaller;


    /**
     * 根据用户ID和机器人ID查询对话
     *
     * @param iddto
     * @return
     */
    public ChatVO query(IDDTO iddto) {
        //创建聊天记录实体对象
        ChatHistory chatHistory = new ChatHistory();
        chatHistory.setRobotId(Long.valueOf(iddto.getRobotId()));
        Long userId = currentUserSupport.getCurrentUserId();
        chatHistory.setUserId(userId);

        RobotRepoEntity robot=robotRepository.queryByRobotId(Long.valueOf(iddto.getRobotId()));
        Long viewtimes=robot.getViewTimes();
        robot.setViewTimes(viewtimes+1);
        robotMapper.updataViewTimes(robot.getId(),robot.getViewTimes());

        ChatVO chatVO = new ChatVO();
        List<ChatHistory> chatHistories = chatMapper.queryByUserIdAndRobotId(chatHistory, chatHistoryNumber);
        chatVO.setChatHistories(chatHistories);
        chatVO.setUserId(iddto.getUserId());
        chatVO.setRobotId(iddto.getRobotId());
        return chatVO;
    }

    @Autowired
    private CurrentUserSupport currentUserSupport;

    @Autowired
    private IntegralService integralService;

    // 用户发送消息，执行对话。
    public Flux<String> sendChat(SendMessageDTO sendMessageDTO, MultipartFile fileFromChatRoom) throws Exception {
        boolean isEnough = integralService.isIntegralEnough(currentUserSupport.getCurrentUserId().intValue());
        if(!isEnough) {
            throw  new BusinessException("您的积分不足");
        };
        // file不为空，进入对话框文件解析流程。否则，进入常规流程。
        // 文件解析流程：文件发给算法embadding，等文件embadding完，再执行对话流程,return。。

        // todo 补一下逻辑。
        Long fileID=null;
        if (fileFromChatRoom!=null&&fileFromChatRoom.getSize()>0){
            fileID=282L;
        }
        // 先将新消息插入数据库
        setNewChatToDB(sendMessageDTO,fileID);

        // TODO 传给算法端，接口没出
        // TODO 更新机器人热度
        //查询机器人信息
        IDDTO iddto = new IDDTO();
        iddto.setRobotId(sendMessageDTO.getRobotId());

        QueryRobotDetailDTO queryRobotDetailDTO = new QueryRobotDetailDTO();
        queryRobotDetailDTO.setNeedActionUnitList(true);
        queryRobotDetailDTO.setRobotId(iddto.getRobotId());

        List<ActionUnit> actionUnits = actionUnitMapper.selectByRobotId(Long.parseLong(queryRobotDetailDTO.getRobotId()));


        // 并行处理任务，获取异步结果
        List<CompletableFuture<Object>> futures = new ArrayList<>();
        AtomicReference<ExcelStreamRequest> echarts = new AtomicReference<>();
        AtomicReference<PictureStreamRequest> paints = new AtomicReference<>();
        actionUnits.stream().forEach(actionUnit -> {
            if (actionUnit.getUnitTemplateCode() != null && "ai_big_model_make_echart".equals(actionUnit.getUnitTemplateCode())) {
                echarts.set(new ExcelStreamRequest().builder()
                        .action("echarts")
                        .input(new ExcelStreamRequest.Input()
                                .builder()
                                .query(sendMessageDTO.getMessage())
                                .build())
                        .build());
            } else if (actionUnit.getUnitTemplateCode() != null && "ai_big_model_make_picture".equals(actionUnit.getUnitTemplateCode())) {
                paints.set(new PictureStreamRequest().builder()
                        .action("paint")
                        .input(new PictureStreamRequest.Input().builder()
                                .prompt(sendMessageDTO.getMessage())
                                .build())
                        .config(new PictureStreamRequest.Config().builder()
                                .model("dall-e-3")
                                .size("1024x1024")
                                .build())
                        .build());
            }
        });

        ExcelStreamRequest excelStreamRequest = echarts.get();
        PictureStreamRequest pictureStreamRequest = paints.get();
        if (excelStreamRequest != null) {
            return algorithmCaller.echartsChat(excelStreamRequest);
        } else if (pictureStreamRequest != null) {
            return algorithmCaller.pictureChat(pictureStreamRequest);
        }

        String tempString = "";
        for (int p = 0; p < actionUnits.size(); p++) {
            if (actionUnits.get(p).getUnitTemplateCode() != null && ActionUnitTemplateCode.ai_big_model_text_chat.getValue().equals(actionUnits.get(p).getUnitTemplateCode())) {
                JSONObject jsonObject = new JSONObject(actionUnits.get(p).getDetail());
                tempString= jsonObject.getStr("characterSetting");
            }
            if (actionUnits.get(p).getUnitTemplateCode() != null && "knowledge".equals(actionUnits.get(p).getUnitTemplateCode())) {
                // embedding 知识库中的文件
                List<File> bulkFiles = fileMapper.selectIdsByRobotid(Long.parseLong(queryRobotDetailDTO.getRobotId()));
                List<String> file_id_list = bulkFiles.stream().map(file -> file.getId().toString()).collect(Collectors.toList());
                CompletableFuture<Object> future = algorithmCaller.handleTask(sendMessageDTO, file_id_list, "embedding-search",threadPoolExecutor);
                futures.add(future);
            } else if (actionUnits.get(p).getUnitTemplateCode() != null && "pdf_parser".equals(actionUnits.get(p).getUnitTemplateCode())) {
                // 文件解析
                JSONObject jsonObject = new JSONObject(actionUnits.get(p).getDetail());

                // 获取 fileList 数组
                JSONArray fileList = jsonObject.getJSONArray("fileList");
                ArrayList<String> file_list_ids = new ArrayList<>();
                // 遍历数组并提取 fileId
                for (int i = 0; i < fileList.size(); i++) {
                    JSONObject fileObject = fileList.getJSONObject(i);
                    String fileId = (String) fileObject.get("fileId");
                    file_list_ids.add(fileId);
                }
                CompletableFuture<Object> future = algorithmCaller.handleTask(sendMessageDTO, file_list_ids, "content-search",threadPoolExecutor);

                futures.add(future);
            }
        }
//        actionUnits.stream().forEach(actionUnit -> {
//            
//        });
        
        ArrayList<String> embeddingStrs = new ArrayList<>();
        // 等待所有任务完成并获取结果
        List<Object> responses = futures.stream()
                .map(future -> {
                    try {
                        return future.get();
                    } catch (InterruptedException | ExecutionException e) {
                        // 处理超时或其他异常情况
                        System.out.println("Task failed: " + e.getMessage());
                        return null;
                    }
                })
                .collect(Collectors.toList());
        for (Object respons : responses) {
            if (respons instanceof RecallApiResponse) {
                RecallApiResponse rApiResponse = (RecallApiResponse) respons;
                List<RecallApiResponseOutput> output = rApiResponse.getData().getOutput();
                for (RecallApiResponseOutput recallApiResponseOutput : output) {
                    String content = recallApiResponseOutput.getContent();
                    embeddingStrs.add(content);

                }
            }
        }
        List<ChatTextStreamRequest.History> historyList = buildHistoryList(sendMessageDTO);

        return algorithmCaller.textChat(sendMessageDTO.getMessage(),embeddingStrs,historyList,sendMessageDTO.getRobotId(),tempString);
    }

    private void setNewChatToDB(SendMessageDTO sendMessageDTO,Long fileID){
        ChatHistory chatHistory = new ChatHistory();
        chatHistory.setUserId(Long.valueOf(sendMessageDTO.getUserId()));
        chatHistory.setRobotId(Long.valueOf(sendMessageDTO.getRobotId()));
        chatHistory.setHistoryContent(sendMessageDTO.getMessage());
        if (sendMessageDTO.getMessageType()!=null){
            chatHistory.setHistoryType(sendMessageDTO.getMessageType());
        }else {
            chatHistory.setHistoryType(sendMessageDTO.getMessageType());
        }


        chatHistory.setFileId(0);
        chatHistory.setHistoryCharacter(1);
        if (fileID!=null){
            chatHistory.setFileId(fileID.intValue());
        }
        chatMapper.create(chatHistory);
    }

    private List<ChatTextStreamRequest.History> buildHistoryList(SendMessageDTO sendMessageDTO){
        //查询历史消息记录
        ChatHistory queryChatHistory = new ChatHistory();
        queryChatHistory.setRobotId(Long.valueOf(sendMessageDTO.getRobotId()));
        queryChatHistory.setUserId(Long.valueOf(sendMessageDTO.getUserId()));
        List<ChatHistory> chatHistories = chatMapper.queryByUserIdAndRobotId(queryChatHistory, messageSendNumber);

        List<ChatTextStreamRequest.History> historyList = new ArrayList<>();
        //是否开启新对话
        boolean newChat = false;
        for (ChatHistory history : chatHistories) {
            ChatTextStreamRequest.History historyElement = new ChatTextStreamRequest.History();
            historyElement.setContent(history.getHistoryContent());
            historyElement.setRole("user");
            historyList.add(historyElement);
            if (newChat) {
                continue;
            }
            if (history.getHistoryType() == 2) {
                newChat = true;
            }
        }
        return historyList;
    }

    public String sendImageChat(MultipartFile file) throws Exception{
        System.out.println("打印下喽,"+file.getName());
        System.out.println("打印下喽,"+file.getOriginalFilename());
        List<String> resImageList= algorithmCaller.uploadFileAndGetImages(file);
        if (resImageList.size()>0){
            return resImageList.get(0);
        }
        System.out.println("打印下喽err,"+resImageList);
        return "http://47.96.231.221:19000/1315118570895572992/101-%E7%81%B0%E8%89%B2%E5%8D%AB%E8%A1%A3.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=faqs7AE7LtUirwnBbUX7%2F20241207%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20241207T165141Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=6449b7602c66b303c0fda83a4d8d9ce161b837320c15bbfcf9e1670f0b9cd011";
    }

}
